/***************************************************************************
 *   Copyright (C) 2008 by Rysiek Krï¿½l,,,   *
 *   rysiek@Babylon2   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "commentdialog.h"
#include "viewerconstants.h"
#include "utils.h"
#include "picturemanager.h"
#include "imageloader.h"

#include <zlib.h>
#include <rexifdata.h>

#include <QDomDocument>
#include <QDomElement>
#include <QDir>
#include <QTextCodec>

#ifdef WINDOWS
#include <windows.h>
#endif

/**
* Konstruktor Klasy
*/
CommentDialog::CommentDialog(QListWidget *listWidget, QWidget* parent, Qt::WFlags fl)
        : QDialog( parent, fl ), Ui::CommentDialog()
{
    setupUi(this);
    PictureManager *manager = dynamic_cast<PictureManager*>(parent);
    if(!manager->getIsPresentationMode()){
    for (int i=0; i<listWidget->count();i++)
    {
        if (listWidget->item(i)->isSelected())
            this->selectedList.append(dynamic_cast<PictureListWidgetItem*>(listWidget->item(i)));
    }
    } else {
     this->selectedList.append(dynamic_cast<PictureListWidgetItem*>(listWidget->item(manager->getItsLoader()->getCurrentIndex())));
    }
    this->timeStampEdit->setDisplayFormat("dd.MMMM.yyyy hh:mm");
    this->setSlots();
    this->timeStampEdit->setEnabled(false);
    this->setComments();

}
/**
* Destruktor Klasy
*/
CommentDialog::~CommentDialog()
{
}

/**
* ÅÄczy SygnaÅy ze slotami
*/
void CommentDialog::setSlots()
{
    connect(this->timeActionCombo, SIGNAL (currentIndexChanged(int)), this, SLOT (comboActionChanged(int)));
}

/*$SPECIALIZATION$*/
void CommentDialog::reject()
{
    QDialog::reject();
}

/**
* Akcja po klikniÄciu przycisku OK
*/
void CommentDialog::accept()
{
    bool changeNote = false;
    bool changePlace = false;
    bool changeTimeStamp = false;

    if (this->note != this->noteEdit->toPlainText()) changeNote = true;
    if (this->place != this->placeEdit->text()) changePlace = true;
    if (this->timeStamp != this->timeStampEdit->dateTime()&&this->timeActionCombo->currentIndex()!=0) changeTimeStamp = true;
    if (!changeNote && !changePlace && !changeTimeStamp)
    {
        this->done(1);
    }
    else
    {
        this->buildCommentString(changeNote,changePlace,changeTimeStamp);
    }
}

/**
* Ustawia odpowiednie dane komentarza w konkretnych polach
*/
void CommentDialog::setComments()
{
    this->note = this->selectedList.at(0)->getNote();
    this->place = this->selectedList.at(0)->getPlace();
    this->timeStamp = this->selectedList.at(0)->getDateTime();

    RExifData *exifData = new RExifData(this->selectedList.at(0)->getFile().absoluteFilePath().toUtf8().data());
    if (!exifData->isExif())
    {
        this->timeActionCombo->removeItem(3);
    }
    if (this->selectedList.size()>1)
        for (int i=1;i<this->selectedList.size();i++)
        {
            if (this->note != this->selectedList.at(i)->getNote()) this->note = "";
            if (this->place != this->selectedList.at(i)->getPlace()) this->place = "";
            if (this->timeStamp != this->selectedList.at(i)->getDateTime()) this->timeStamp = QDateTime::fromTime_t(0);
        }
    this->noteEdit->setPlainText(this->note);
    this->placeEdit->setText(this->place);
    this->timeStampEdit->setDateTime(this->timeStamp);
    delete exifData;
}

/**
* Buduje QString do zapisania w pliku z komentarzem i wywoÅuje metode zapisujÄcÄ
*/
void CommentDialog::buildCommentString(bool changeNote, bool changePlace, bool changeTimeStamp)
{
    QDomDocument doc;

    for (int i=0; i<this->selectedList.size(); i++)
    {
        if (this->selectedList.at(i)->getCommentString().isEmpty() )
        {
            doc = this->buildNewComment();
        }
        else
        {
            doc.setContent(this->selectedList.at(i)->getCommentString());
        }
        if (changeNote)
        {
            QDomElement rootElement = doc.firstChildElement("Comment");
            QDomElement oldElement = rootElement.firstChildElement("Note");
            QDomElement newElement = doc.createElement("Note");
            QDomText t = doc.createTextNode(this->noteEdit->toPlainText());
            newElement.appendChild(t);
            rootElement.replaceChild(newElement, oldElement);
        }
        if (changePlace)
        {
            QDomElement rootElement = doc.firstChildElement("Comment");
            QDomElement oldElement = rootElement.firstChildElement("Place");
            QDomElement newElement = doc.createElement("Place");
            QDomText t = doc.createTextNode(this->placeEdit->text());
            newElement.appendChild(t);
            rootElement.replaceChild(newElement, oldElement);
        }
        if (changeTimeStamp)
        {
            QDomElement rootElement = doc.firstChildElement("Comment");
            QDomElement oldElement = rootElement.firstChildElement("Time");
            QDomElement newElement = doc.createElement("Time");
            QDomText t;
            if (this->timeActionCombo->currentIndex()==3)
            {
                RExifData *exifData = new RExifData(this->selectedList.at(i)->getFile().absoluteFilePath().toUtf8().data());
                t = doc.createTextNode(QString::number(exifData->getDate().toTime_t()));
                delete exifData;
            }
            else
            {
                if (this->timeStampEdit->dateTime().toTime_t()!=0)
                {
                    int w = this->timeStampEdit->dateTime().toTime_t();
                    t = doc.createTextNode(QString::number(w));
                }
                else
                {
                    t = doc.createTextNode("");
                }
            }
            newElement.appendChild(t);
            rootElement.replaceChild(newElement, oldElement);
        }
        QString commentString = Utils::encodeCharacters(doc.toString());


        this->writeComment(commentString ,i);
    }
}

/**
* archiwizuje i zapisuje do pliku komentarz
* @Param commentString - komentarz
* @param itemIndex - numer indexu pliku w thia->selectedList
*/
void CommentDialog::writeComment(QString commentString, int itemIndex)
{
    QFileInfo fileInfo = this->selectedList.at(itemIndex)->getFile();
    QDir dir = fileInfo.dir();
    if (!dir.exists(".comments")) dir.mkdir(".comments");
    dir.cd(".comments");
    //setting comment directory windows attribute to hidden
#ifdef WINDOWS
    LPCTSTR winFileName = (LPCTSTR) dir.absolutePath().toStdString ().c_str()
                          SetFileAttributes( winFileName ,FILE_ATTRIBUTE_HIDDEN);
    delete winFileName;
#endif
    QString fileName = fileInfo.fileName();
    fileName = fileName + ".xml";
    fileName = dir.filePath(fileName);
    char buf[commentString.size()];
    QByteArray array = commentString.toLocal8Bit();
    char* buffer = array.data();
    for (int i=0; i < commentString.size();i++)
    {
        buf[i] = *buffer++;
    }
    gzFile pliczek;
    const char *filePath;
    array = fileName.toLocal8Bit();
    filePath = array.data();
    pliczek = gzopen ( filePath, "wb" );
    gzwrite(pliczek, buf, sizeof(buf));
    gzclose(pliczek);
    this->done(1);
}


/**
* ZarzÄdza zachowaniem this->timeStampEdit w przypadku zmiany opcji w thia->timeActionCombo
* @param action - numer indexu na ktÃ³ry zmienia siÄ akcja
*/
void CommentDialog::comboActionChanged(int action)
{
    switch (action)
    {
    case(0):
                    this->timeStampEdit->setEnabled(false);
        this->timeStampEdit->setDateTime(this->timeStamp);
        break;
    case(1):
                    this->timeStampEdit->setEnabled(true);
        break;
    case(2):
                    this->timeStampEdit->setEnabled(false);
        this->timeStampEdit->setDateTime(QDateTime::currentDateTime());
        break;
    case(3):
                    this->timeStampEdit->setEnabled(false);
        RExifData *exifData = new RExifData(this->selectedList.at(0)->getFile().absoluteFilePath().toUtf8().data());
        if (exifData->isExif())
{
            this->timeStampEdit->setDateTime(exifData->getDate());
        }
        delete exifData;
        break;
    }
}

/**
* Builds new comment XML document. In Future there have to be XML classes
*/
QDomDocument CommentDialog::buildNewComment()
{
    QDomDocument doc("");

    /*   QDomElement root = doc.createElement("Comment");
       root.setAttribute("format", "2.0");
       doc.appendChild(root);

       QDomElement element = doc.createElement("Note");
       root.appendChild(element);
       element = doc.createElement("Place");
       root.appendChild(element);
       element = doc.createElement("Time");
       root.appendChild(element);
       element = doc.createElement("Keywords");
       root.appendChild(element);
    QDomText
    */
    QString docString = "<?xml version=\"1.0\"?>\n<Comment format=\"2.0\"><Place></Place><Time></Time><Note/><Keywords></Keywords></Comment>";
    doc.setContent(docString);
    return doc;

}

